#include "adc6140.h"
#include "gpio.h"
#include "main.h"
// #include "sai.h"
#include "cmsis_os.h"
#include "elog.h"

#define LOG_TAG "adc6140"
#define _ADC6140_DELAY_MS(x)                                  \
    if (osKernelGetState() == osKernelRunning)                \
    {                                                         \
        osDelay(x); /* 延时函数, HAL_Delay(x) / osDelay(x) */ \
    }                                                         \
    else                                                      \
    {                                                         \
        HAL_Delay(x);                                         \
    }

// static adc6140_dev_t *adc6140_device = NULL;

void TLV320ADC6140_ReadRegister(adc6140_handle_t dev, uint8_t regAddr);
uint8_t TLV320ADC6140_Config(adc6140_handle_t dev, uint8_t regAddr, uint8_t data);

adc6140_handle_t adc6140_create(SPI_HandleTypeDef *hspi, GPIO_TypeDef *g, uint16_t p)
{
    if (hspi == NULL || g == NULL)
    {
        return NULL;
    }

    adc6140_dev_t *adc6140_device;
    adc6140_device = (adc6140_dev_t *)calloc(1, sizeof(adc6140_dev_t));

    adc6140_device->gpio = g;
    adc6140_device->pin = p;
    adc6140_device->spi_dev = hspi;

    return (adc6140_handle_t)adc6140_device;
}

uint8_t TLV320ADC6140_Init(adc6140_handle_t dev)
{
    uint8_t ret = 0;
    
    if (dev == NULL)
    {
        log_e("TLV320ADC6140_Init  adc6140_device = NULL fail !!!");
        return 1;
    }

    // 初始化配置
    _ADC6140_DELAY_MS(100);
    ret |= TLV320ADC6140_Config(dev, ADCX140_SLEEP_CFG, 0x81); // 唤醒 0x02
    _ADC6140_DELAY_MS(10);
    ret |= TLV320ADC6140_Config(dev, ADCX140_PAGE_SELECT, 0x00);   // 页选 0x00
    ret |= TLV320ADC6140_Config(dev, ADCX140_ASI_CFG0, 0x00);      // TDM 16-bits 0x07
    ret |= TLV320ADC6140_Config(dev, ADCX140_ASI_CFG1, 0x00);      // tx_offset = 0  0x08
    ret |= TLV320ADC6140_Config(dev, ADCX140_ASI_CFG2, 0x00);      // 0x08
    ret |= TLV320ADC6140_Config(dev, ADCX140_ASI_CH1, 0x00);       // slot 0 0x0b
    ret |= TLV320ADC6140_Config(dev, ADCX140_ASI_CH2, 0x01);       // slot 1 0x0c
    ret |= TLV320ADC6140_Config(dev, ADCX140_ASI_CH3, 0x02);       // slot 2 0x0d
    ret |= TLV320ADC6140_Config(dev, ADCX140_ASI_CH4, 0x03);       // slot 3 0x0e
    ret |= TLV320ADC6140_Config(dev, ADCX140_MST_CFG0, 0x01);      // slave mode 0x13
    ret |= TLV320ADC6140_Config(dev, ADCX140_CLK_SRC, 0x10);       // ratio = 64 0x16
    ret |= TLV320ADC6140_Config(dev, ADCX140_CH1_CFG0, 0x30);      // ch1 Microphone - single - DC - 2.5K 0x3c
    ret |= TLV320ADC6140_Config(dev, ADCX140_CH2_CFG0, 0x30);      // ch2 0x41
    ret |= TLV320ADC6140_Config(dev, ADCX140_CH3_CFG0, 0x30);      // ch3 0x46
    ret |= TLV320ADC6140_Config(dev, ADCX140_CH4_CFG0, 0x30);      // ch4 0x4b
    ret |= TLV320ADC6140_Config(dev, ADCX140_CH1_CFG1, 0x00);      // channel gain = 0db 0x3d
    ret |= TLV320ADC6140_Config(dev, ADCX140_CH2_CFG1, 0x00);      // 0x42
    ret |= TLV320ADC6140_Config(dev, ADCX140_CH3_CFG1, 0x00);      // 0x47
    ret |= TLV320ADC6140_Config(dev, ADCX140_CH4_CFG1, 0x00);      //  0x4c
    ret |= TLV320ADC6140_Config(dev, ADCX140_GPIO_CFG0, 0x02);     // gpio1 disabled 0x21
    ret |= TLV320ADC6140_Config(dev, ADCX140_IN_CH_EN, 0xF0);      // enable input ch 0x73
    ret |= TLV320ADC6140_Config(dev, ADCX140_ASI_OUT_CH_EN, 0xF0); // enable output ch 0x74
    ret |= TLV320ADC6140_Config(dev, ADCX140_PWR_CFG, 0xE0);       // power_up adc micbias  0x75
    // _ADC6140_DELAY_MS(100);

    // start trans
    //  HAL_SAI_Receive_DMA(&hsai_BlockA3, (uint8_t*)sai_buffer, BUFFER_SIZE);

    // _ADC6140_DELAY_MS(10);
    // TLV320ADC6140_ReadRegister(dev, ADCX140_MST_CFG0);
    // TLV320ADC6140_ReadRegister(dev, ADCX140_MST_CFG1);
    // TLV320ADC6140_ReadRegister(dev, ADCX140_ASI_STS);

    return ret;
}

void TLV320ADC6140_ReadRegister(adc6140_handle_t dev, uint8_t regAddr)
{

    uint8_t readCommand[2] = {regAddr << 1 | 0x01, 0};
    // 保存读取数据
    uint8_t rxData[2] = {0};

    adc6140_dev_t *p_device = (adc6140_dev_t *)dev;

    HAL_GPIO_WritePin(p_device->gpio, p_device->pin, GPIO_PIN_RESET);
    HAL_SPI_TransmitReceive(p_device->spi_dev, readCommand, rxData, 2, 0xf);
    HAL_GPIO_WritePin(p_device->gpio, p_device->pin, GPIO_PIN_SET);

    //	HAL_SPI_TransmitReceive(&hspi4, readCommand, rxData, 2, HAL_MAX_DELAY);
    //	HAL_SPI_TransmitReceive(&hspi4, readCommand, rxData, 2, HAL_MAX_DELAY);
    log_d("regAddr 0x%x Status : 0x%x", regAddr, rxData[1]);
}

uint8_t TLV320ADC6140_Config(adc6140_handle_t dev, uint8_t regAddr, uint8_t data)
{
    uint8_t ret = 0;

    // 构造写入命令
    uint8_t writeCommand[2] = {regAddr << 1, data};
    // 构造读取命令
    uint8_t readCommand[2] = {regAddr << 1 | 0x01, data};
    // 保存读取数据
    uint8_t rxData[2] = {0};

    adc6140_dev_t *p_device = (adc6140_dev_t *)dev;

    // 写寄存器
    HAL_GPIO_WritePin(p_device->gpio, p_device->pin, GPIO_PIN_RESET);
    HAL_SPI_Transmit(p_device->spi_dev, writeCommand, 2, 0xf);
    while (HAL_SPI_GetState(p_device->spi_dev) != HAL_SPI_STATE_READY)
        ;
    HAL_GPIO_WritePin(p_device->gpio, p_device->pin, GPIO_PIN_SET);
    _ADC6140_DELAY_MS(5);
    // 读寄存器
    HAL_GPIO_WritePin(p_device->gpio, p_device->pin, GPIO_PIN_RESET);
    HAL_SPI_TransmitReceive(p_device->spi_dev, readCommand, rxData, 2, 0xf);
    while (HAL_SPI_GetState(p_device->spi_dev) != HAL_SPI_STATE_READY)
        ;
    HAL_GPIO_WritePin(p_device->gpio, p_device->pin, GPIO_PIN_SET);

    if (data == rxData[1])
    {
        // log_d("regAddr 0x%x Write 0x%x success",regAddr,data);
        ret = 0;
    }
    else
    {
        ret = 1;
        log_e("regAddr 0x%x Write 0x%x Fail, value 0x%x", regAddr, data, rxData[1]);
    }
    _ADC6140_DELAY_MS(10);

    return ret;
}
